package gestores;

import ferramentas.Seguranca;
import ferramentas.UtensiliosParaDatas;
import java.io.IOException;
import java.util.Calendar;
import java.util.Hashtable;
import java.util.List;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import sistema.Transaccao;
import sistema.Utilizador;

public class GestorUtilizadores extends HttpServlet {

    Calendar calendar = Calendar.getInstance();

    /**
     * Processes requests for both HTTP <code>GET</code> and <code>POST</code> methods.
     * @param request servlet request
     * @param response servlet response
     * @throws ServletException if a servlet-specific error occurs
     * @throws IOException if an I/O error occurs
     */
    protected void processRequest(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        HttpSession session = request.getSession();
        String accao = request.getParameter("accao");

        if (accao.equals(GestorUtilizadores.INSERIR_UTILIZADOR)) {
            try {
                inserirUtilizador(request, response, session);
            } catch (Exception e) {
                e.printStackTrace();
            }
        } else if (accao.equals(GestorUtilizadores.ALTERAR_UTILIZADOR)) {
            try {
                alterarUtilizador(request, response, session);
            } catch (Exception ex) {
                ex.printStackTrace();
            }
        } else if (accao.equals(GestorUtilizadores.DEPOSITO)) {
            try {
                depositoUtilizador(request, response, session);
            } catch (Exception ex) {
                ex.printStackTrace();
            }
        } else if (accao.equals(GestorUtilizadores.LEVANTAMENTO)) {
            try {
                fazerLevantamento(request, response, session);
            } catch (Exception ex) {
                ex.printStackTrace();

            }
        } else if (accao.equals(GestorUtilizadores.HISTORICO)) {
            try {
                visualizarTransaccoes(request, response, session);
            } catch (Exception ex) {
                ex.printStackTrace();

            }
        }
    }

    // <editor-fold defaultstate="collapsed" desc="HttpServlet methods. Click on the + sign on the left to edit the code.">
    /**
     * Handles the HTTP <code>GET</code> method.
     * @param request servlet request
     * @param response servlet response
     * @throws ServletException if a servlet-specific error occurs
     * @throws IOException if an I/O error occurs
     */
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        processRequest(request, response);
    }

    /**
     * Handles the HTTP <code>POST</code> method.
     * @param request servlet request
     * @param response servlet response
     * @throws ServletException if a servlet-specific error occurs
     * @throws IOException if an I/O error occurs
     */
    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        processRequest(request, response);
    }

    /**
     * Returns a short description of the servlet.
     * @return a String containing servlet description
     */
    @Override
    public String getServletInfo() {
        return "Short description";
    }// </editor-fold>

    public void inserirUtilizador(HttpServletRequest request, HttpServletResponse response, HttpSession session) throws IOException {
        // ver SE é necessario ir outra vez validar os campos dos dados, pq talvez s devia fazer na camada do layout
        //agora ta só a validaçao de dados repetidos verifica se ja existe o email
        if (dadosValidos(request)) {
            //cria um novo utilizador na bd
            Hashtable<String, String> dados_pessoais = criaTabelaUtilizador(request);
            try {
                Utilizador.insere(dados_pessoais);
                session.setAttribute("excepcao", "Ocorreu um erro enquanto se tentava registar! Tente Novamente!");
            } catch (Exception ex) {
                ex.printStackTrace();
                session.setAttribute("excepcao", "Não foi possível executar esta acção. Dados incorrectos. Tente novamente!");
                response.sendRedirect("/Projecto_PR/mostra_erro.jsp");
            }
            response.sendRedirect("/Projecto_PR/mostra_sucesso.jsp");
        } else {
            session.setAttribute("excepcao", "Não foi possível efectuar o registo, pois os dados que inseriu são inválidos. Tente novamente!");
            response.sendRedirect("/Projecto_PR/mostra_erro.jsp");
        }

    }

    public void alterarUtilizador(HttpServletRequest request, HttpServletResponse response, HttpSession session) throws IOException {
        if (request.getParameter("sub_accao").equals("primeira")) {

            Long id = Long.parseLong(request.getParameter("id"));
            Utilizador u = null;
            try {
                u = Utilizador.devolvePorId(id);
            } catch (Exception ex) {
                session.setAttribute("excepcao", "Não foi possível executar esta acção. Tente novamente!");
                response.sendRedirect("/Projecto_PR/mostra_erro.jsp");
                ex.printStackTrace();
            }
            session.removeAttribute("utilizador");
            session.setAttribute("utilizador", u);
            response.sendRedirect("/Projecto_PR/alterar_utilizador.jsp");
        } else if (request.getParameter("sub_accao").equals("segunda")) {

            //apos ter os layouts tentar perceber se temos as subaccoes como no RHPLUS
            Hashtable<String, String> dados = new Hashtable<String, String>();
            dados.put("var_nome", request.getParameter("nome"));
            dados.put("var_apelido", request.getParameter("apelido"));
            dados.put("var_dataNasc", request.getParameter("dataNasc"));
            dados.put("var_morada", request.getParameter("morada"));
            dados.put("var_localidade", request.getParameter("localidade"));
            dados.put("var_codigoPostal", request.getParameter("codigoP"));
            dados.put("var_telefone", request.getParameter("telefone"));
            dados.put("var_bi", request.getParameter("bi"));
            dados.put("var_idutilizador", request.getParameter("id"));
            try {
                Utilizador.altera(dados);
                session.removeAttribute("utilizador");
                Utilizador u = Utilizador.devolvePorId(Long.parseLong(request.getParameter("id")));
                session.setAttribute("utilizador", u);
            } catch (Exception ex) { // mandar tmb erro na session e fazer devido reencaminhamento
                session.setAttribute("excepcao", "Não foi possível executar esta acção. Tente novamente!");
                response.sendRedirect("/Projecto_PR/mostra_erro.jsp");
                ex.printStackTrace();
            }
            response.sendRedirect("/Projecto_PR/index.jsp");
        }
    }

    public void depositoUtilizador(HttpServletRequest request, HttpServletResponse response, HttpSession session) throws IOException {

        if (request.getParameter("accao").equals("fazer_deposito")) {
            Hashtable<String, String> dados_deposito = new Hashtable<String, String>();

            Double valor = Double.parseDouble(request.getParameter("valor"));
            dados_deposito.put("var_valor", valor.toString());

            dados_deposito.put("var_tipo", "deposito");

            Calendar c = Calendar.getInstance();
            String data = UtensiliosParaDatas.devolveDataEmString(c.get(Calendar.YEAR), c.get(Calendar.MONTH), c.get(Calendar.DATE));
            dados_deposito.put("var_data", data);

            Long id = ((Utilizador) session.getAttribute("utilizador")).getId_utilizador();
            dados_deposito.put("var_idutilizador", id.toString());

            try {
                Utilizador.insereTransaccao(dados_deposito);
                Double saldo = Utilizador.devolveSaldo(id);
                Double total = saldo + valor;

                Hashtable<String, String> dados_actualizar = new Hashtable<String, String>();
                dados_actualizar.put("var_saldo", total.toString());
                dados_actualizar.put("var_idutilizador", id.toString());
                Utilizador.actualizaSaldo(dados_actualizar);
            } catch (Exception ex) {
               session.setAttribute("excepcao", "Não foi possível executar esta acção. Tente novamente!");
                ex.printStackTrace();
                response.sendRedirect("/Projecto_PR/mostra_erro.jsp");
            }
            session.removeAttribute("utilizador");
            try {
                session.setAttribute("utilizador", Utilizador.devolvePorId(id));
            } catch (Exception ex) {
                ex.printStackTrace();
                session.setAttribute("excepcao", "Não foi possível executar esta acção. Tente novamente!");
                response.sendRedirect("/Projecto_PR/mostra_erro.jsp");
            }
            response.sendRedirect("/Projecto_PR/index.jsp");

        } else {
            IllegalArgumentException illegal_argument_exception = new IllegalArgumentException();
            session.setAttribute("excepcao", illegal_argument_exception.toString());
            response.sendRedirect("/Projecto_PR/mostra_erro.jsp");
        }
    }

    public void fazerLevantamento(HttpServletRequest request, HttpServletResponse response, HttpSession session) throws IOException {

        if (request.getParameter("accao").equals("fazer_levantamento")) {

            Long id = ((Utilizador) session.getAttribute("utilizador")).getId_utilizador();

            Hashtable<String, String> dados_levantamnt = new Hashtable<String, String>();
            dados_levantamnt.put("var_valor", request.getParameter("valor"));
            dados_levantamnt.put("var_tipo", "levantamento");

            Calendar c = Calendar.getInstance();
            String data = UtensiliosParaDatas.devolveDataEmString(c.get(Calendar.YEAR), c.get(Calendar.MONTH), c.get(Calendar.DATE));
            dados_levantamnt.put("var_data", data);
            dados_levantamnt.put("var_idutilizador", id.toString());

            try {

                Double saldo = Utilizador.devolveSaldo(id);
                Double valor_alevantar = Double.parseDouble(request.getParameter("valor"));
                if (saldo >= valor_alevantar) {

                    Utilizador.insereTransaccao(dados_levantamnt);

                    Double total = saldo - valor_alevantar;
                    Hashtable<String, String> dados_actualizar = new Hashtable<String, String>();
                    dados_actualizar.put("var_saldo", total.toString());
                    dados_actualizar.put("var_idutilizador", id.toString());

                    Utilizador.actualizaSaldo(dados_actualizar);

                } else {
                    session.setAttribute("excepcao", "Não foi possível executar esta acção, o seu saldo é insuficiente. Tente novamente!");
                    response.sendRedirect("/Projecto_PR/mostra_erro.jsp");
                }
            } catch (Exception ex) {
                ex.printStackTrace();
                session.setAttribute("excepcao", "Não foi possível executar esta acção. Tente novamente!");
                response.sendRedirect("/Projecto_PR/mostra_erro.jsp");
            }

            session.removeAttribute("utilizador");
            try {
                session.setAttribute("utilizador", Utilizador.devolvePorId(id));
            } catch (Exception ex) {
                ex.printStackTrace();
                session.setAttribute("excepcao", "Não foi possível executar esta acção. Tente novamente!");
                response.sendRedirect("/Projecto_PR/mostra_erro.jsp");
            }
            response.sendRedirect("/Projecto_PR/index.jsp");
        } else {
            IllegalArgumentException illegal_argument_exception = new IllegalArgumentException();
            session.setAttribute("excepcao", illegal_argument_exception.toString());
            response.sendRedirect("/Projecto_PR/mostra_erro.jsp");
        }
    }

    public void visualizarTransaccoes(HttpServletRequest request, HttpServletResponse response, HttpSession session) throws IOException {

        Long id = ((Utilizador) session.getAttribute("utilizador")).getId_utilizador();
        List<Transaccao> lista_trans = null;
        session.removeAttribute("lista_transaccoes");
        if (request.getParameter("subaccao").equals("todos")) {
            try {
                lista_trans = Transaccao.seleccionarTodos(id);
            } catch (Exception ex) {
                ex.printStackTrace();
                response.sendRedirect("/Projecto_PR/mostra_erro.jsp");
            }
        } else if (request.getParameter("subaccao").equals("levantamentos")) {
            try {
                lista_trans = Transaccao.seleccionarTodosLevantamentos(id);
            } catch (Exception ex) {
                ex.printStackTrace();
                session.setAttribute("excepcao", "Não foi possível executar esta acção. Tente novamente!");
                response.sendRedirect("/Projecto_PR/mostra_erro.jsp");
            }
        } else if (request.getParameter("subaccao").equals("depositos")) {
            try {
                lista_trans = Transaccao.seleccionarTodosDepositos(id);
            } catch (Exception ex) {
                ex.printStackTrace();
                session.setAttribute("excepcao", "Não foi possível executar esta acção. Tente novamente!");
                response.sendRedirect("/Projecto_PR/mostra_erro.jsp");
            }
        } else {
            //ERRO!!!!!!!!!!! pq nao tem accao associada
            IllegalArgumentException illegal_argument_exception = new IllegalArgumentException();
            session.setAttribute("excepcao", illegal_argument_exception.toString());        
            response.sendRedirect("/Projecto_PR/mostra_erro.jsp");
            
        }
        session.setAttribute("lista_transaccoes", lista_trans);
        response.sendRedirect("/Projecto_PR/historico_transaccao.jsp");
    }

    public Hashtable criaTabelaUtilizador(HttpServletRequest request) {
        Hashtable<String, String> dados = new Hashtable<String, String>();
        dados.put("var_nome", request.getParameter("nome").trim());
        dados.put("var_apelido", request.getParameter("apelido").trim());
        dados.put("var_dataNasc", request.getParameter("dataNasc").trim());
        dados.put("var_morada", request.getParameter("morada").trim());
        dados.put("var_localidade", request.getParameter("localidade").trim());
        dados.put("var_codigoPostal", request.getParameter("prefixo").trim() + "-" + request.getParameter("sufixo").trim());
        dados.put("var_telefone", request.getParameter("telefone").trim());
        dados.put("var_email", request.getParameter("email").trim());
        dados.put("var_password", Seguranca.converteParaMD5(request.getParameter("password").trim()));
        dados.put("var_perfil", "utilizador");
        dados.put("var_bi", request.getParameter("bi"));
        dados.put("var_saldo", "0.0");
        
        return dados;
    }

    private boolean dadosValidos(HttpServletRequest request) {
        try {
            return !Utilizador.existeEmail(request.getParameter("email"));
        } catch (Exception ex) {
            ex.printStackTrace();
            return false;
        }
    }
    public static final String INSERIR_UTILIZADOR = "inserir_utilizador";
    public static final String ALTERAR_UTILIZADOR = "alterar_utilizador";
    public static final String VISUALIZAR_UTILIZADOR = "visualizar_utilizador";
    public static final String DEPOSITO = "fazer_deposito";
    public static final String LEVANTAMENTO = "fazer_levantamento";
    public static final String HISTORICO = "ver_transaccoes";
}
